package com.siashan.toolkit.oss.minio.core;

import com.siashan.toolkit.oss.core.OssResult;
import com.siashan.toolkit.oss.core.OssStorageService;
import com.siashan.toolkit.oss.core.enums.OssChannel;
import com.siashan.toolkit.oss.core.exception.ToolkitOssException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * MinIO存储
 *
 * @author siashan
 * @date 2024/2/6
 */
@Slf4j
public class MinioOssStorageService extends OssStorageService {
    /**
     * MinIO OSS客户端
     */

    private MinioClient client;
    /**
     * 阿里云OSS配置
     */
    private MinioOssConfig config;


    /**
     * 默认构造方法
     * <p>
     * 初始化阿里云配置
     */
    public MinioOssStorageService() {
        config = new MinioOssConfig();
        config.setAccessKeyId(MinioOssConfiguration.getAccessKeyId());
        config.setAccessKeySecret(MinioOssConfiguration.getAccessKeySecret());
        config.setBucketName(MinioOssConfiguration.getBucketName());
        config.setEndpoint(MinioOssConfiguration.getEndpoint());
        config.setRegion(MinioOssConfiguration.getRegin());
        config.setPrefix(MinioOssConfiguration.getPrefix());
        config.setDomain(MinioOssConfiguration.getDomain());
        init();
    }

    /**
     * 构造方法
     *
     * @param config 阿里云配置
     */
    public MinioOssStorageService(MinioOssConfig config) {
        this.config = config;
        init();
    }

    /**
     * 初始化阿里云客户端
     */
    private void init() {
        client = MinioClient.builder()
                .endpoint(config.getEndpoint())
                .credentials(config.getAccessKeyId(), config.getAccessKeySecret())
                .build();
    }

    /**
     * 文件上传
     *
     * @param data 文件字节数组
     * @param path 文件路径，包含文件名
     * @return Oss上传结果
     */
    @Override
    public OssResult upload(byte[] data, String path) {
        return upload(new ByteArrayInputStream(data), path);
    }

    /**
     * 文件上传
     *
     * @param inputStream 字节流
     * @param path        文件路径，包含文件名
     * @return Oss上传结果
     */
    @Override
    public OssResult upload(InputStream inputStream, String path) {
        try {
            client.putObject(PutObjectArgs.builder()
                    .bucket(config.getBucketName()) // 存储桶
                    .object(path) // 文件名
                    .stream(inputStream, inputStream.available(), -1) // 文件内容
//                    .contentType(file.getContentType()) // 文件类型
                    .build());
        } catch (Exception e) {
            throw new ToolkitOssException("上传文件失败，请检查配置信息", e);
        }


        return OssResult.build(path, config.getDomain(), OssChannel.MinIO);
    }

    /**
     * 文件上传
     *
     * @param data   文件字节数组
     * @param suffix 文件后缀  eg: .gif .txt .png
     * @return Oss上传结果
     */
    @Override
    public OssResult uploadSuffix(byte[] data, String suffix) {
        return upload(data, getPath(config.getPrefix(), suffix));
    }

    /**
     * 文件上传
     *
     * @param inputStream 字节流
     * @param suffix      后缀
     * @return Oss上传结果
     */
    @Override
    public OssResult uploadSuffix(InputStream inputStream, String suffix) {
        return upload(inputStream, getPath(config.getPrefix(), suffix));
    }

    /**
     * 文件删除
     *
     * @param fileName 资源名称
     * @return 是否成功标识
     * @since 1.0.2
     */
    @Override
    public boolean remove(String fileName) {
        try {
            client.removeObject(RemoveObjectArgs.builder()
                    .bucket(config.getBucketName()) // 存储桶
                    .object(fileName) // 文件名
                    .build());
        } catch (Exception e) {
            log.error("MinIOn 文件删除失败", e);
            return false;
        }
        return true;
    }
}
